#ifndef __PACKET_JSON__
#define __PACKET_JSON__

#include <functional>
#include "IUtility.h"
#include "IPacket.h"
#include "ISysResources.h"
#include "libjson.h"

//typedef rapidjson::GenericValue<rapidjson::UTF8<>, rapidjson::CrtAllocator> JsonValue;

//using namespace JSONode;

class CPacketJson: public virtual IPacket
{
private:
INIT_CLASS_PRODUCT( CPacketJson ) 

public:
	const bool Init( const void * pvdPara, char * pszMsgTxt, int iMsgTxtSize );
	const void UnInit() override final;
	const char * Key();
	void SetKey(const char * pszKey);
	const char * MSG_FLG();
	void SetMsgFlg(const char * pszMsgFlg);
    const int MSG_CODE() const;
	const char * MSG_TEXT() const;
	const char * LBM_NO() const;
	const int TIME() const;
	void SetTime(const unsigned long ulTime);
	long long SOURCE_PROCESS_ID();
	void SetSourceProcessID(long long llProID);
	const bool UpdFirstSet( const int &iMsgCode, const char * pszMsgText, const char * LbmNo );
	long long DESTINATION_PROCESS_ID();
	void SetDestinationProcessID(long long llProID);
    const bool TOP_FLAG();
    void SetTopFlag(const bool bTopFlg);

    const bool Parse(const char * pszData, int iLne = 0);
	void * Append();
	const int RECORD_COUNT(const char * pszTableName);
	void * ReadRecord(const char * pszTableName, int iRecNo);
	const bool Save(const char * pszTableName, void * ptrRecInfo);
	const bool TableExist(const char * pszTableName);
	const bool FieldExist(void * ptrRecInfo, const char * pszFieldName);
	const int FieldType(void * ptrRecInfo, const char * pszFieldName);
	const bool DeleteField(const char * pszTableName, const char * pszFieldName);
	const void Clear(const char * pszTableName = nullptr);
	const bool EmptyFlg(const char * pszTableName);
	const int DataSize();
	
	const bool ChangeTableName(const char * pszOldName, const char * pszNewName);
	const bool ChangeFieldName(void * ptrRecInfo, const char * pszOldName, const char * pszNewName);
	const char * GetFieldValueAsString(void * ptrRecInfo, const char * pszFieldName, const char * pszDefVal = "");
	const long long GetFieldValueAsInt(void * ptrRecInfo, const char * pszFieldName, const int iDefVal = 0);
	const double  GetFieldValueAsDouble(void * ptrRecInfo, const char * pszFieldName, const double dDefVal = 0);
	const bool  GetFieldValueAsBool(void * ptrRecInfo, const char * pszFieldName, const bool bDefVal = false);
	void * GetFieldValueAsPtr(const char * pszTableName, int iRowNo,  const char * pszFieldName);
	const bool SetFieldValue(void * ptrRecInfo, const char * pszFieldName, const char *pszValue);
	const bool SetFieldValue(void * ptrRecInfo, const char * pszFieldName, const long long llValue);
	const bool SetFieldValue(void * ptrRecInfo, const char * pszFieldName, const double dValue);
	const bool SetFieldValue(void * ptrRecInfo, const char * pszFieldName, const bool bValue);
	const void * SetFieldValue(const char * pszTableName, const char * pszFieldName, void * ptrValue, void * ptrDeleter);
	const char * AsString(void * ptrPara = nullptr);
	const char * AsString(const char * pszName, char ** pszBuf, unsigned long &ulLen);
	const bool CopyRecord(const char * pszSouTableName, const int iBgnPos, const int iEndPos, IPacket * ptrDesPacket, const char * pszDesTableName);
	const bool AppendRecord(const char * pszTableName, void * pvdRecord, bool bLockFlg);
	const int FieldCount( const char * pszTableName );
	const bool FieldNameInfo(const char * pszTableName, void * ptrvtFieldName);
	const bool FieldNameInfo(const char * pszTableName, char ** pszFieldNameList);
	const int GetQueueKey();
	const void SetQueueKey(const int iQueueKey);

private:
    JSONNode m_clRoot;
    json_string m_strBody;
	//rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> m_clRoot;
	JSONNode * m_ptrFirstdResultSetRecord;

	shared_ptr<IStrFun> m_ptrStrFun;
	shared_ptr<ILock> m_ptrLock, m_ptrTableLock;
	map<string, void *> m_mpPtr;
	map<string, function<void(void *)>> m_mpDeleter;
	int m_iQueueKey, m_iLen;
private:
    void InitT0();
	JSONNode * AssignRecord(JSONNode * ptrRecord);
	void AddRecord(const char * pszTableName, JSONNode * ptrRecord);
	const bool _FieldExist(void * ptrRecInfo, const char * pszFieldName);
};

#endif//__PACKET_JSON__